home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / hydrabbsa8 / source / src.lha / node / Node_Serial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-08  |  8.7 KB  |  354 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <dos/dos.h>
  8.  
  9. #include <devices/serial.h>
  10. #include <hardware/cia.h>
  11.  
  12. #include <clib/exec_protos.h>
  13. #include <clib/alib_protos.h>
  14. #include <clib/dos_protos.h>
  15.  
  16. #define NOTMAIN
  17.  
  18. #define ClrSignal(s)  SetSignal(0,s)
  19.  
  20. #include "/common/types.h"
  21. #include "/common/defines.h"
  22. #include "/common/structures.h"
  23. #include "/common/strings.h"
  24. #include "/common/errors.h"
  25. #include "/common/shared_protos.h"
  26. #include "/common/Files.h"
  27.  
  28. #include "Node_Input_protos.h"
  29. #include "Node_Console_protos.h"
  30. #include "/library/hbbscommon_protos.h"
  31. #include "/library/hbbscommon_pragmas.h"
  32. #include "nodelibrary/hbbsnode_protos.h"
  33. #include "nodelibrary/hbbsnode_pragmas.h"
  34.  
  35. extern struct NodeData *N_ND;
  36. extern struct BBSGlobalData *BBSGlobal;
  37. extern struct Library *HBBSCommonBase;
  38. extern struct Library *HBBSNodeBase;
  39.  
  40.  
  41. void CleanupSerial( void )
  42. {
  43.   if (!N_ND->NodeDevice.SysopNode)
  44.   {
  45.     if (N_ND->SerBuffer)
  46.     {
  47.       if (N_ND->SerPort)
  48.       {
  49.         if (N_ND->SerWrite)
  50.         {
  51.           if (N_ND->SerOPEN)
  52.           {
  53.             if (N_ND->SerRead)
  54.             {
  55.               AbortSerRead(); // will only abort id request submitted..
  56.               FreeVec(N_ND->SerRead);
  57.             }
  58.             CloseDevice((struct IORequest*)N_ND->SerWrite);
  59.             N_ND->SerOPEN=FALSE;
  60.           }
  61.           DeleteExtIO((struct IORequest*)N_ND->SerWrite);
  62.         }
  63.         DeletePort(N_ND->SerPort);
  64.       }
  65.       FreeVec(N_ND->SerBuffer);
  66.     }
  67.   }
  68.   N_ND->SerOK=FALSE;
  69. }
  70.  
  71. void SerReset( void )
  72. {
  73.   // this routine reads in all waiting data from the serial port and then dumps it!
  74.   UBYTE *mem;
  75.   ULONG bytes;
  76.  
  77.   if (bytes=SerQueryData())
  78.   {
  79.     if (mem=AllocVec(bytes,MEMF_PUBLIC))
  80.     {
  81.       WaitSerReadBlock(mem,bytes); // *C* ooh naughty.. should really have somekind of wait() here..
  82.       FreeVec(mem);
  83.     }
  84.   }
  85. }
  86.  
  87. V_BOOL OpenSerial( void )
  88. {
  89.   N_ND->SerWaiting=FALSE;
  90.   N_ND->SerOK=FALSE;
  91.   N_ND->SerOPEN=FALSE;
  92.   if (!N_ND->NodeDevice.SysopNode)
  93.   {
  94.     if (N_ND->SerBuffer=AllocVec(DEF_SERBUFLEN,MEMF_PUBLIC))
  95.     {
  96.       N_ND->SerBufferLen=DEF_SERBUFLEN;
  97.       if (N_ND->SerPort=CreatePort(0,0))
  98.       {
  99.         if (N_ND->SerWrite = (struct IOExtSer *) CreateExtIO(N_ND->SerPort,(ULONG)sizeof(struct IOExtSer)))
  100.         {
  101.           N_ND->SerWrite->io_SerFlags       = SERF_SHARED|SERF_7WIRE|SERF_XDISABLED|SERF_RAD_BOOGIE;
  102.           if (!(OpenDevice((STRPTR)N_ND->NodeDevice.SerialDevice,(ULONG)N_ND->NodeDevice.SerialUnit,(struct IORequest *)N_ND->SerWrite,0L) ))
  103.           {
  104.             N_ND->SerOPEN=TRUE;
  105.             // kill data waiting..
  106.             N_ND->SerWrite->IOSer.io_Command  = CMD_RESET;
  107.             DoIO((struct IORequest *)N_ND->SerWrite);
  108.  
  109.  
  110.             // setup port with correct baud rate etc..
  111.             N_ND->SerWrite->IOSer.io_Command  = SDCMD_SETPARAMS;
  112.             N_ND->SerWrite->io_SerFlags       |= SERF_XDISABLED;
  113.             N_ND->SerWrite->io_Baud           = N_ND->NodeDevice.SerialBaud;
  114.             DoIO((struct IORequest *)N_ND->SerWrite);
  115.  
  116.  
  117.             if (N_ND->SerRead = (struct IOExtSer*)AllocVec(sizeof(struct IOExtSer),MEMF_PUBLIC) )
  118.             {
  119.               // duplicate data...
  120.               memcpy(N_ND->SerRead,N_ND->SerWrite,sizeof(struct IOExtSer));
  121.               SerReset();
  122.               N_ND->SerOK=TRUE;
  123.               return(TRUE);
  124.             }
  125.           }
  126.           else HBBS_DoErrorMessage(EMSG_NODEVICE,N_ND->NodeNum,NULL);
  127.         }
  128.       }
  129.     }
  130.     CleanupSerial();
  131.   }
  132.   return(FALSE);
  133. }
  134.  
  135. ULONG ModemGetLine( void )
  136. {
  137.   ULONG ReturnedSigs;
  138.   UBYTE CurrentChar[2]={0,0}; // 2 chars, use ¤tchar for null terminated string type..
  139.   ULONG retval=IN_NOTHING; // this must NOT be returned to the caller!!!!!
  140.  
  141.   struct TimerData *TD;
  142.  
  143.   N_ND->CurrentLine[0]=0; // null terminate the string..
  144.  
  145.   if (TD=SubmitTimer(N_ND->NodeTimer,N_ND->NodeDevice.MaxCommandWait,0))
  146.   {
  147.     do
  148.     {
  149.       if (!N_ND->SerWaiting) SendSerReadData();
  150.  
  151.       // we cant use SetupSigs() and WaitAllSigs() because if we are resetting
  152.       // the modem after a LOGIN_LOCAL sersigs is set to 0... :-)
  153.       // *C* add timeout
  154.       N_ND->SerSig=DEF_SERSIG;
  155.       N_ND->TimerSig=DEF_TIMERSIG;
  156.       ReturnedSigs=Wait(N_ND->SerSig | N_ND->TimerSig);
  157.  
  158.       while (HandleSerSigs(ReturnedSigs) && retval==IN_NOTHING)
  159.       {
  160.         // ok, we got some data from somehwere...
  161.  
  162.         CurrentChar[0]=N_ND->IBuffer[0];
  163.  
  164.         if (CurrentChar[0]>=0x20 && CurrentChar[0]!=127) // i.e. not unprintable or a control char..
  165.         {
  166.           strcat(N_ND->CurrentLine,CurrentChar);
  167.         }
  168.         else
  169.         {
  170.           if (CurrentChar[0]=='\n')
  171.           {
  172.             if (strlen(N_ND->CurrentLine)>0) retval=IN_GOTLINE;
  173.           }
  174.         }
  175.       }
  176.  
  177.       if ((retval==IN_NOTHING) && (CheckTimer(N_ND->NodeTimer,TD)))
  178.       {
  179.         TD=NULL;
  180.         retval=IN_TIMEOUT;
  181.       }
  182.     }
  183.     while (retval==IN_NOTHING);
  184.     if (TD) AbortTimer(N_ND->NodeTimer,TD);
  185.  
  186.     if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  187.     {
  188.       ConWriteStr(N_ND->CurrentLine);
  189.       ConWriteStr(str_CRLF);
  190.     }
  191.     if (N_ND->SerWaiting) AbortSerRead();
  192.   }
  193.   return(retval);
  194. }
  195.  
  196. void ModemError(char *command, char *result)
  197. {
  198.   char errstr[2048]; // big enough ?
  199.  
  200.   if (N_ND->NodeDevice.ModemLog)
  201.   {
  202.     sprintf(errstr,"When Sending the command \"%s\" the modem returned \"%s\"",command,result);
  203.  
  204.     HBBS_LogError(N_ND->NodeSettings.ModemLogFile,ERR_GENERAL,errstr,TYPE_WARNING);
  205.   }
  206. }
  207.  
  208. void TurnEchoOn( void )
  209. {
  210.   struct Node *node;
  211.   short retriesleft;
  212.   BOOL Done;
  213.   ULONG result;
  214.  
  215.  
  216.   PutText("\033[37;0m\n");
  217.   for (node=N_ND->NodeDevice.TurnOnEcho->lh_Head;node->ln_Succ;node=node->ln_Succ)
  218.   {
  219.     if (node->ln_Name)
  220.     {
  221.       Done=FALSE;
  222.       retriesleft=N_ND->NodeDevice.EchoRetries;
  223.       do
  224.       {
  225.         if (retriesleft!=N_ND->NodeDevice.EchoRetries)
  226.         {
  227.           ConWriteStr("Retrying Modem...\n\r");
  228.         }
  229.  
  230.         retriesleft--;
  231.         Delay(N_ND->NodeDevice.TurnOnEchoDelay);
  232.         SerReset();
  233.         SerWriteStr(node->ln_Name);
  234.         SerWriteStr(str_CRLF);
  235.         if (result=ModemGetLine()==IN_GOTLINE)
  236.         {
  237.           // ok, got some input..
  238.  
  239.           if (stricmp(node->ln_Name,N_ND->CurrentLine)==0)
  240.           {  // echo is already on, so discard this line and read another line..
  241.             result=ModemGetLine();
  242.           }
  243.           if (result==IN_GOTLINE)
  244.           {
  245.             if (stricmp("OK",N_ND->CurrentLine)==0) Done=TRUE;
  246.           }
  247.         }
  248.       } while (!Done && retriesleft>0);
  249.     }
  250.   }
  251.   SerReset();
  252. }
  253.  
  254. V_BOOL SendModemString(char *str)
  255. {
  256.   ULONG err=1;
  257.   ULONG loop,loop2=N_ND->NodeDevice.CommandRetries;
  258.   BOOL linemismatch;
  259.  
  260.   do
  261.   {
  262.  
  263.     // this loop sends the command to the modem and wait for the characters to
  264.     // be echoed back.  if we don't get back what we send we try it again!
  265.  
  266.     loop=N_ND->NodeDevice.CommandRetries;
  267.     do
  268.     {
  269.       Delay(N_ND->NodeDevice.DelayBetweenCmds);
  270.       SerReset(); //clear all crap before we send our new string..
  271.       SerWriteStr(str);
  272.       SerWriteStr(str_CRLF);
  273.       ModemGetLine();
  274.       if (linemismatch=(stricmp(str,N_ND->CurrentLine)!=0 ? TRUE : FALSE))
  275.       {
  276.         TurnEchoOn();
  277.       }
  278.     } while (loop-- && linemismatch);
  279.  
  280.     // right if we are here then we know we're gonna get a blank line and a timeout
  281.     // or OK OR ERROR..  if we don't get OK then we retry the command...
  282.     ModemGetLine();
  283.  
  284.   } while (loop2-- && stricmp(N_ND->CurrentLine,"OK")!=0 && (err=stricmp(N_ND->CurrentLine,"ERROR"))==0);
  285.   if (!err) ModemError(str,N_ND->CurrentLine);
  286.   return(err);
  287. }
  288.  
  289. void OffHook( void )
  290. {
  291.   SendModemString(N_ND->NodeDevice.OffHookString);
  292. }
  293.  
  294. void ReOpenSerial( void )
  295. {
  296.   V_SMALLNUM loop=N_ND->NodeDevice.ReOpenRetries;
  297.   if (!N_ND->NodeDevice.SysopNode)
  298.   {
  299.     CleanupSerial();
  300.  
  301.     while (loop-- && N_ND->SerOK==FALSE)
  302.     {
  303.       Delay(N_ND->NodeDevice.ReOpenDelay);
  304.       OpenSerial();
  305.     }
  306.  
  307.     if (!N_ND->SerOK)
  308.     {
  309.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,ESTR_NOSERIAL,TYPE_CRITICAL);
  310.     }
  311.   }
  312. }
  313.  
  314. void HangUp( void )
  315. {
  316.   struct Node *node;
  317.  
  318.   if (!N_ND->NodeDevice.NullModemCable)
  319.   {
  320.     if (!N_ND->NodeDevice.DropDTRHangup)
  321.     {
  322.       for (node=N_ND->NodeDevice.CommandModeString->lh_Head;node->ln_Succ;node=node->ln_Succ)
  323.       {
  324.         if (node->ln_Name) SerWriteStr(node->ln_Name);
  325.       }
  326.       SendModemString(N_ND->NodeDevice.HangUpString);
  327.     }
  328.     ReOpenSerial();
  329.     OffHook();
  330.   }
  331.   else
  332.   {
  333.     ReOpenSerial();
  334.   }
  335. }
  336.  
  337. V_BOOL InitModem( void )
  338. {
  339.   struct Node *node;
  340.  
  341.   if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  342.   {
  343.     ConWriteStr("Initialising Modem...\n\r");
  344.   }
  345.  
  346.   TurnEchoOn();
  347.   for (node=N_ND->NodeDevice.ModemInit->lh_Head;node->ln_Succ;node=node->ln_Succ)
  348.   {
  349.     if (node->ln_Name) SendModemString(node->ln_Name);
  350.   }
  351.   return(TRUE);
  352. }
  353.  
  354.